
package JET.physics.interfaces;

import JET.Centers.ControlCenter;
import JET.Scene;
import java.util.ArrayList;

/**
 *
 * @author 057Ry
 */
public class ProjectTreeSceneFilterNode implements ProjectTreeNode {

    protected ArrayList<ProjectTreeSceneFilterNode> filterNodes;
    protected ArrayList<Scene> scenes;

    private String filterName;

    public ProjectTreeSceneFilterNode() {
        this.filterName = "SceneFilter";
        clear();
    }

    public ProjectTreeSceneFilterNode(String filterName) {
        this.filterName = filterName;
        clear();
    }

    public void clear() {
        filterNodes = new ArrayList<ProjectTreeSceneFilterNode>();
        scenes = new ArrayList<Scene>();
    }

    public ProjectTreeSceneFilterNode getNodeOwningScene(Scene s) {
        if (scenes.contains(s))
            return this;

        for(ProjectTreeSceneFilterNode f : filterNodes) {
            ProjectTreeSceneFilterNode node = f.getNodeOwningScene(s);
            if (node!=null)
                return node;
        }

        return null;
    }

    /**
     * If specified path doesn't exist, this method builds it.
     * @param path Array of filter names.
     */
    public void buildFilterPath(String[] path) {
        if (path==null) return;

        // If path starts with this filter name then skip first path element ...
        if (path[0].equals(this.filterName)) {
            if (path.length==1) return;

            String[] newPath = new String[path.length-1];
            for(int i=0; i<path.length-1; i++)
                newPath[i] = path[i+1];
            path = newPath;
        }

        boolean has = false;
        for(ProjectTreeSceneFilterNode f : filterNodes)
            if (f.filterName.equals(path[0]))
                has = true;

        ProjectTreeSceneFilterNode node = getFilterNodeByName(path[0]);
        if (node==null) {
            node = new ProjectTreeSceneFilterNode();
            node.setFilterName(path[0]);
            filterNodes.add(node);
        }

        if (path.length>1) {
            String[] newPath = new String[path.length-1];
            for(int i=0; i<path.length-1; i++)
                newPath[i] = path[i+1];

            node.buildFilterPath(newPath);
        }
    }

    public String getScenePath(Scene scene) {

        String path = "";
        ProjectTreeSceneFilterNode node = getNodeOwningScene(scene);

        while(node!=null) {
            path = node.filterName +"/"+ path;
            node = ProjectTreeSceneFilterNode.getParent(node, this);
        }

        System.out.println("path: "+path);

        //path = path.substring(path.indexOf("/")+1);
        // ommit last slash ...
        return "".equals(path) ? "" : path.substring(0, path.length()-1);
    }

    public void setFilterName(String filterName) {
        this.filterName = filterName;
    }

    public void addFilterNode(ProjectTreeSceneFilterNode newFilterNode) {
        filterNodes.add(newFilterNode);
    }
    public void removeFilterNode(ProjectTreeSceneFilterNode filterNode) {
        filterNodes.remove(filterNode);
    }

    public ProjectTreeSceneFilterNode getFilterNodeByName(String name) {
        if (this.filterName.equals(name))
            return this;

        for(ProjectTreeSceneFilterNode f : filterNodes)
            if (f.filterName.equals(name))
                return f;
        
        return null;
    }

    public ProjectTreeSceneFilterNode getFilterNodeByNameDeep(String name) {
        if (this.filterName.equals(name))
            return this;

        for(ProjectTreeSceneFilterNode f : filterNodes) {
            ProjectTreeSceneFilterNode node = f.getFilterNodeByNameDeep(name);
            if (node!=null)
                return node;
        }

        return null;
    }

    public void addScene(Scene scene) {
        scenes.add(scene);
    }
    public void removeScene(Scene scene) {
        scenes.remove(scene);
    }

    public ProjectTreeNode getChild(int index) {
        int fnSize = filterNodes.size();
        if (index<fnSize)
            return filterNodes.get(index);
        else
            return (ProjectTreeNode) scenes.get(index-fnSize);
    }

    public int getChildCount() {
        return filterNodes.size() + scenes.size();
    }

    public boolean isLeaf() {
        return filterNodes.isEmpty() && scenes.isEmpty();
    }

    public int getIndexOfChild(Object child) {
        if (child instanceof ProjectTreeSceneFilterNode)
            return filterNodes.indexOf(child);
        else if (child instanceof Scene)
            return scenes.indexOf(child) + filterNodes.size();
        else
            return -1;
    }

    public void resetNodeValue(Object o) {
        if (o instanceof String)
            setFilterName((String) o);
    }

    @Override
    public String toString() {
        return filterName;
    }

    ////////////////////////////////////////////////////////////////////////////
    //                        STATIC UTILS PART                               //
    ////////////////////////////////////////////////////////////////////////////

    /**
     * Recursively looks for parent of specified node, starting at root node.
     * @param node Node that parent we are looking for.
     * @param root Search tree root node.
     * @return Parent node of nedo, or null if node is root or is not part of tree.
     */
    public static ProjectTreeSceneFilterNode getParent(ProjectTreeSceneFilterNode node, ProjectTreeSceneFilterNode root) {
        if (root.filterNodes.contains(node))
            return root;

        for(ProjectTreeSceneFilterNode f : root.filterNodes) {
            ProjectTreeSceneFilterNode parent = getParent(node, f);
            if (parent!=null)
                return parent;
        }

        return null;

    }
}
